package top.scsoul.voes.system.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.scsoul.voes.common.core.domain.model.UserSearchVo;
import top.scsoul.voes.common.core.domain.model.UserVo;
import top.scsoul.voes.common.exception.SystemException;
import top.scsoul.voes.common.utils.ExcelExportDownloadUtil;
import top.scsoul.voes.common.core.domain.entity.Role;
import top.scsoul.voes.common.core.domain.entity.User;
import top.scsoul.voes.common.core.domain.entity.UserRole;
import top.scsoul.voes.system.mapper.UserMapper;
import top.scsoul.voes.system.mapper.UserRoleMapper;
import top.scsoul.voes.system.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * (User)表服务实现类
 *
 * @author guolei
 * @since 2021-08-8 00:13:23
 */
@Slf4j
@Transactional
@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Autowired
    UserRoleMapper userRoleMapper;

    @Autowired
    PasswordEncoder passwordEncoder;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public User queryById(Integer id) {
        return this.userMapper.queryById(id);
    }

    @Override
    public PageInfo<User> queryAll(UserSearchVo userSearchVo, int currentPage, int pageSize) {
        User user = new User();
        user.setUsername(userSearchVo.getUsername());
        user.setPhone(userSearchVo.getPhone());
        user.setState(userSearchVo.getState());
        PageHelper.startPage(currentPage, pageSize);
        List<User> users = userMapper.queryAll(user);
        return new PageInfo<User>(users);
    }


    @Override
    public User queryByUsername(String username) {
        return this.userMapper.queryByUsername(username);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Deprecated
    @Override
    public List<User> queryAllByLimit(int offset, int limit) {
        return this.userMapper.queryAllByLimit(offset, limit);
    }

    /**
     * 查询多条数据
     * see queryAll
     *
     * @param currentPage 当前页
     * @param pageSize    查询条数
     * @return 对象列表
     */
    @Deprecated
    @Override
    public PageInfo<User> selectPage(int currentPage, int pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<User> users = userMapper.queryAll(null);
        return new PageInfo<>(users);
    }

    /**
     * 新增数据
     *
     * @param userVo 实例对象
     * @return 实例对象
     */
    @Override
    public User insert(UserVo userVo) {
        if (userMapper.queryByUsername(userVo.getUsername()) != null) {
            throw new SystemException("用户已经存在");
        }
        User user = new User();
        user.setUsername(userVo.getUsername());
        user.setPassword(passwordEncoder.encode(userVo.getPassword()));
        user.setName(userVo.getName());
        user.setGender(userVo.getGender());
        user.setIdCard(userVo.getIdCard());
        user.setPhone(userVo.getPhone());
        user.setState(userVo.getState());
        user.setCreated(new Date());
        userMapper.insert(user);
        Integer primaryKey = userMapper.queryByUsername(userVo.getUsername()).getId();
        log.info("primaryKey:{}", primaryKey);
        List<Integer> roleIds = userVo.getRoleIds();
        if (roleIds != null && roleIds.size() > 0) {
            roleIds.forEach(roleId -> {
                UserRole userRole = new UserRole();
                userRole.setUserId(primaryKey);
                userRole.setRoleId(roleId);
                userRoleMapper.insert(userRole);
                log.info("角色{}", userRole);
            });
        }
        return user;
    }

    /**
     * 修改数据
     *
     * @param userVo 实例对象
     * @return 实例对象
     */
    @Override
    public User update(UserVo userVo) {
        User user = userMapper.queryByUsername(userVo.getUsername());
        user.setUsername(userVo.getUsername());
        user.setPassword(userVo.getPassword());
        user.setName(userVo.getName());
        user.setGender(userVo.getGender());
        user.setIdCard(userVo.getIdCard());
        user.setPhone(userVo.getPhone());
        user.setState(userVo.getState());

        ArrayList<Integer> userOldRoleIds = new ArrayList<>();
        List<Role> roles = user.getRoles();
        if (roles != null && roles.size() > 0) {
            roles.forEach(role -> {
                userOldRoleIds.add(role.getId());
            });
        }
        List<Integer> roleIds = userVo.getRoleIds();
        if (roleIds != null && roleIds.size() > 0) {
            roleIds.forEach(roleId -> {
                if (userOldRoleIds.contains(roleId)) {
                    userOldRoleIds.remove(roleId);
                } else {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(user.getId());
                    userRole.setRoleId(roleId);
                    userRoleMapper.insert(userRole);
                }
            });
        }
        //删除多余的
        if (userOldRoleIds.size() > 0) {
            userOldRoleIds.forEach(oldRoleIds -> {
                userRoleMapper.deleteByUserIdAndRoleId(user.getId(), oldRoleIds);
            });
        }
        userMapper.update(user);
        return queryById(user.getId());
    }

    @Override
    public User update(User user) {
        userMapper.update(user);
        return userMapper.queryByUsername(user.getUsername());
    }

    @Override
    public boolean resetPassword(String username, String password) {
        User user = userMapper.queryByUsername(username);
        user.setPassword(passwordEncoder.encode(password));
        int update = userMapper.update(user);
        return update > 0;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        int i = userMapper.deleteById(id);
        userRoleMapper.deleteByUserId(id);
        return i > 0;
    }

    @Override
    public boolean deleteByIds(List<Integer> ids) {
        userMapper.deleteByIds(ids);
        userRoleMapper.deleteByUserIds(ids);
        return true;
    }

    @Override
    public void exportUser(List<Integer> ids, HttpServletResponse response) throws IOException {
        List<User> userList = userMapper.getByIds(ids);
        ExcelExportDownloadUtil.excelExport(response, userList, User.class, "用户信息表");

    }

    @Override
    public Map<String, Object> importUser(MultipartFile file) throws Exception {
        ImportParams importParams = new ImportParams();
        importParams.setTitleRows(1);
        importParams.setHeadRows(1);
        List<UserVo> userVoList = ExcelImportUtil.importExcel(file.getInputStream(), UserVo.class, importParams);
        AtomicInteger i = new AtomicInteger();
        int total = 0;
        if (userVoList != null && (total = userVoList.size()) > 0) {
            userVoList.forEach(userVo -> {
                try {
                    this.insert(userVo);
                    i.getAndIncrement();
                } catch (SystemException e) {
                    log.error(e.getMessage());
                }
            });
        }
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("total", total);
        map.put("success", i.get());
        return map;
    }

    @Override
    public void getImportExcel(HttpServletResponse response) throws IOException {

    }

    @Override
    public boolean selfResetPsw(String username, String oldPassword, String newPassword) {
        User user = userMapper.queryByUsername(username);
        String dbPassword = user.getPassword();
        boolean matches = passwordEncoder.matches(oldPassword, dbPassword);
        if (matches) {
            user.setPassword(passwordEncoder.encode(newPassword));
            userMapper.updatePsw(user);
            return true;
        }
        throw new SystemException("原密码错误");
    }
}